import 'package:flutter/material.dart';

class WidgetKey extends StatelessWidget {
  WidgetKey({Key? key}) : super(key: key);

  final _globalKey1 = GlobalKey();
  final _globalKey2 = GlobalKey();

  @override
  Widget build(BuildContext context) {
    final orientation = MediaQuery.of(context).orientation;

    return Scaffold(
      appBar: AppBar(title: Text('widgetKey')),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: () {
          final state = _globalKey1.currentState as _CounterState;
          state.setState(() {
            state._num++;
          });
        },
      ),
      body: SafeArea(
        child: Column(children: [
          Flex(
            direction: orientation == Orientation.landscape
                ? Axis.horizontal
                : Axis.vertical,
            children: [Counter(), Counter()],
          ),
          Divider(
            color: Colors.blue,
            height: 10,
            indent: 10,
            endIndent: 10,
          ),
          orientation == Orientation.landscape
              ? Row(
                  children: [
                    Counter(key: _globalKey1),
                    Counter(key: _globalKey2),
                  ],
                )
              : Column(
                  children: [
                    Counter(key: _globalKey1),
                    Counter(key: _globalKey2),
                  ],
                ),
          Divider(
            color: Colors.blue,
            height: 10,
            indent: 10,
            endIndent: 10,
          ),
          Expanded(
            child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceAround,
                children: [
                  SizedBox(
                    width: 100,
                    child: ReorderableBoxs(),
                  ),
                  DraggableBoxs(),
                ]),
          )
        ]),
      ),
    );
  }
}

class Counter extends StatefulWidget {
  const Counter({Key? key}) : super(key: key);

  @override
  _CounterState createState() => _CounterState();
}

class _CounterState extends State<Counter> {
  int _num = 0;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
        onTap: () {
          setState(() {
            _num++;
          });
        },
        child: Container(
            width: 50,
            height: 50,
            alignment: Alignment.center,
            color: Colors.blue[100],
            child: Text(_num.toString(),
                style: TextStyle(fontSize: 20, color: Colors.black))));
  }
}

class ReorderableBoxs extends StatefulWidget {
  const ReorderableBoxs({Key? key}) : super(key: key);

  @override
  _ReorderableBoxsState createState() => _ReorderableBoxsState();
}

class _ReorderableBoxsState extends State<ReorderableBoxs> {
  final _boxs = [
    Box(Colors.blue[100]!, key: UniqueKey()),
    Box(Colors.blue[200]!, key: UniqueKey()),
    Box(Colors.blue[300]!, key: UniqueKey()),
    Box(Colors.blue[400]!, key: UniqueKey()),
    Box(Colors.blue[500]!, key: UniqueKey()),
    Box(Colors.blue[600]!, key: UniqueKey()),
    Box(Colors.blue[700]!, key: UniqueKey()),
  ];

  _shuffle() {
    setState(() {
      _boxs.shuffle();
    });
  }

  @override
  Widget build(BuildContext context) {
    return ReorderableListView(
      onReorder: (int oldIndex, int newIndex) {
        print("moved $oldIndex to $newIndex");
        if (newIndex > oldIndex) {
          //  向下移动
          newIndex--;
        }
        final box = _boxs.removeAt(oldIndex);
        _boxs.insert(newIndex, box);
      },
      children: [
        ..._boxs,
        ElevatedButton(
            key: ValueKey('shuffle-btn'),
            style: ButtonStyle(
                backgroundColor: MaterialStateProperty.all(Colors.blue)),
            onPressed: _shuffle,
            child: FittedBox(
              fit: BoxFit.fitWidth,
              child: Text('shuffle'),
            ))
      ],
    );
  }
}

class Box extends StatelessWidget {
  final Color color;
  const Box(this.color, {Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (BuildContext context, BoxConstraints constraints) {
        print(constraints);
        return Container(
          margin: EdgeInsets.all(5),
          width: 50,
          height: 50,
          color: color,
        );
      },
      // child: Container(
      //   margin: EdgeInsets.all(5),
      //   width: 50,
      //   height: 50,
      //   color: color,
      // ),
    );
  }
}

class DraggableBoxs extends StatefulWidget {
  const DraggableBoxs({Key? key}) : super(key: key);

  @override
  _DraggableBoxsState createState() => _DraggableBoxsState();
}

class _DraggableBoxsState extends State<DraggableBoxs> {
  final _colors = [
    Colors.blue[100]!,
    Colors.blue[200]!,
    Colors.blue[300]!,
    Colors.blue[400]!,
    Colors.blue[500]!,
    Colors.blue[600]!,
    Colors.blue[700]!,
    Colors.blue[800]!
  ];

  int _slot = 0;
  double _stackOffsetTop = 0;

  final _stackGlobalKey = GlobalKey();

  _shuffle() {
    setState(() {
      _colors.shuffle();
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Container(
          width: 100,
          height: 416,
          decoration:
          BoxDecoration(border: Border.all(color: Colors.red)),
          child: Listener(
            onPointerMove: (event){
              final y = event.position.dy - _stackOffsetTop;
              print(y);
              if(y >(_slot+1)*50){
                if(_slot == _colors.length -1) return;
                setState(() {
                  final c = _colors[_slot];
                  _colors[_slot] = _colors[_slot+1];
                  _colors[_slot+1] = c;
                  _slot++;
                });

              }else if (y<(_slot)*50){
                if(_slot == 0) return;
                setState(() {
                  final c = _colors[_slot];
                  _colors[_slot] = _colors[_slot-1];
                  _colors[_slot-1] = c;
                  _slot--;
                });

              }
            },
            child: Stack(
              key:_stackGlobalKey,
              children: List.generate(
                  _colors.length,
                  (index) => Box1(
                        _colors[index],
                        x: 18,
                        y: index * 50,
                        key: ValueKey(_colors[index]),
                    dragStarted: (color){
                          final index = _colors.indexOf(color);
                          _slot = index;
                          print('dragStarted $index');
                          final stackRenderBox = _stackGlobalKey.currentContext?.findRenderObject() as RenderBox;
                          _stackOffsetTop=stackRenderBox.localToGlobal(Offset.zero).dy;
                          print('_stackOffsetTop:$_stackOffsetTop');
                    },
                      )),
            ),
          ),
        ),
        ElevatedButton(
            key: ValueKey('shuffle-btn'),
            style: ButtonStyle(
                backgroundColor: MaterialStateProperty.all(Colors.blue)),
            onPressed: _shuffle,
            child: FittedBox(
              fit: BoxFit.fitWidth,
              child: Text('shuffle'),
            ))
      ],
    );
  }
}

class Box1 extends StatelessWidget {
  final Color color;
  final double x, y;
  final Function(Color)? dragStarted;

  const Box1(this.color, {Key? key, required this.x, required this.y, this.dragStarted})
      : super(key: key);



  @override
  Widget build(BuildContext context) {

    final container =  Container(
      width: 50,
      height: 50,
      color: color,
      margin: EdgeInsets.all(5),
    );

    return AnimatedPositioned(
      duration: Duration(milliseconds : 300),
      top: y,
      left: x,
      child: Draggable(
        onDragStarted: ()=>dragStarted?.call(color),
        child: container,
        feedback: container,
        childWhenDragging: Visibility(
          visible: false,
            child: container,
        ),
      ),
    );
  }
}
